
import styles from './index.module.less';
import React from 'react';
import * as THREE from 'three';
import Controller, { ControllerState } from './Controller';
import IThreeProps from './interface/IThreeProps';
import useRender from './hooks/useRender';
import useToolsManage from './hooks/useToolsManage';

const ThreeContext = React.createContext<Controller>(null as any);

export default class Three extends React.Component<IThreeProps>{

    /** 控制器 */
    static Controller = Controller;

    /** 状态 */
    static ControllerState = ControllerState;

    /** 获取控制器沟子 */
    static useController = () => React.useContext(ThreeContext);

    render() {
        return <Main {...this.props} />
    }
}

function Main(props: IThreeProps) {

    const { controller } = props;

    /** canvas 容器 */
    const cont = controller.useMemo(s => s.cont, []);

    /** 场景 */
    const scene = controller.useMemo(s => s.scene, []);

    const onRef = React.useCallback((e: HTMLDivElement | null) => { controller.pipeline(async s => { s.cont = e })() }, [controller])

    useRender(controller);
    useToolsManage(controller);

    // 创建核心对象
    React.useEffect(() => {
        controller.createThree(cont);
    }, [cont, controller])

    // 渲染水平面
    React.useEffect(() => {
        if (!scene) return;

        const helper = new THREE.GridHelper(1000, 1000);
        helper.position.y = 0;
        (helper.material as THREE.Material).opacity = 0.25;
        (helper.material as THREE.Material).transparent = true;
        scene.add(helper);

        const ground = new THREE.Mesh(new THREE.PlaneGeometry(40, 40, 1, 1), new THREE.MeshPhongMaterial({ color: 0xffffff, shininess: 150 }))
        ground.rotation.x = - Math.PI / 2; // rotates X/Y to X/Z
        ground.receiveShadow = true;
        scene.add(ground);
    }, [scene])

    return (
        <ThreeContext.Provider value={controller} >
            <div ref={onRef} className={styles.three} />
        </ThreeContext.Provider>
    )
}